﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using Consul;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using MicroService.ClientDemo.Models;
using MicroService.Interface;
using MicroService.Model;

namespace MicroService.ClientDemo.Controllers
{
    public class HomeController : Controller
    {
        private readonly ILogger<HomeController> _logger;
        private readonly IUserService _userService;

        public HomeController(ILogger<HomeController> logger, IUserService userService)
        {
            _logger = logger;
            _userService = userService;
        }

        public IActionResult Index()
        {
            //代码的一小步，架构的一大步 单体变分布式
            //ViewBag.Users = _userService.UserAll();

            string url = "http://MicroService/api/users/all"; //调用服务的组名---湖人队
            //其实consul做了什么事？ DNS域名解析

            #region consul

            ConsulClient client = new ConsulClient(c =>
            {
                c.Address = new Uri("http://localhost:8500");
                c.Datacenter = "dc1";
            });

            var response = client.Agent.Services().Result.Response;
            //foreach (var item in response)
            //{
            //    Console.WriteLine("***********************");
            //    Console.WriteLine(item.Key);
            //    var service = item.Value;

            //    Console.WriteLine($"{service.Address}--{service.Port}--{service.Service}");
            //    Console.WriteLine("***********************");
            //}
            Uri uri = new Uri(url);
            string groupName = uri.Host;
            var servicesList = response.Where(s =>
                s.Value.Service.Equals(groupName, StringComparison.OrdinalIgnoreCase)).ToArray();//找出全部的湖人队球员，其实就是服务组里的成员

            //{
            //    url = $"{uri.Scheme}://{servicesList.First().Value.Address}:{servicesList.First().Value.Port}{uri.PathAndQuery}";//直接拿第一个
            //}
            //负载均衡策略
            AgentService agentService = null;
            //{
            //    //平均策略 多个实例，平均分配---随机就是平均
            //    agentService =
            //        servicesList[new Random(DateTime.Now.Millisecond + iSeed++).Next(0, servicesList.Count())].Value;//添加随机种子，为了更加随机
            //}
            //{
            //    //轮询策略----很僵化
            //    agentService = servicesList[iSeed++ % servicesList.Length].Value;
            //}
            {
                //能不能根据服务器的情况来分配----权重-----不同的实例权重不同---配置权重
                //集合种1权重一个，5权重5个，10权重就有10个，然后在总数集合随机
                List<KeyValuePair<string, AgentService>> pairsList = new List<KeyValuePair<string, AgentService>>();
                foreach (var pair in servicesList)
                {
                    int count = int.Parse(pair.Value.Tags?[0]);
                    for (int i = 0; i < count; i++)
                    {
                        pairsList.Add(pair);
                    }
                }

                agentService = pairsList.ToArray()[new Random(iSeed++).Next(0, pairsList.Count())].Value;
            }

            url = $"{uri.Scheme}://{agentService.Address}:{agentService.Port}{uri.PathAndQuery}";
            #endregion

            //string url = "http://localhost:5266/api/users/all";
            string content = InvokeApi(url);
            ViewBag.Users = Newtonsoft.Json.JsonConvert.DeserializeObject<IEnumerable<User>>(content);
            return View();
        }

        private int iSeed;

        public IActionResult Privacy()
        {
            return View();
        }

        [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
        public IActionResult Error()
        {
            return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
        }

        public static string InvokeApi(string url)
        {
            using (HttpClient httpClient = new HttpClient())
            {
                HttpRequestMessage message = new HttpRequestMessage();
                message.Method = HttpMethod.Get;
                message.RequestUri = new Uri(url);
                var result = httpClient.SendAsync(message).Result;
                string content = result.Content.ReadAsStringAsync().Result;
                return content;
            }
        }
    }
}
